﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Security.Cryptography.X509Certificates;

namespace EmissorCTE
{
    /// <summary>
    /// Manipulação de certificados.
    /// </summary>
    class certificado
    {

        #region Variavel
        /// <summary>
        /// Armazena os certificados dos clientes em execucao
        /// </summary>
        private static Hashtable htCertificados;

        #endregion

        #region GetCertificadoEnvio

        public static X509Certificate2 GetCertificado(string SerialNumber, string FileNme, string Password)
        {
            if (htCertificados == null)
            {
                htCertificados = new Hashtable();
                if (string.IsNullOrEmpty(SerialNumber))
                {
                    htCertificados.Add(FileNme, GetCertificadoArquivo(FileNme, Password));
                    return (X509Certificate2)htCertificados[FileNme];
                }
                else
                {
                    htCertificados.Add(SerialNumber, GetCertificadoCSP(SerialNumber));
                    return (X509Certificate2)htCertificados[SerialNumber];
                }
            }
            else
            {
                if (string.IsNullOrEmpty(SerialNumber))
                {
                    if (htCertificados[FileNme] == null)
                        htCertificados.Add(FileNme, GetCertificadoArquivo(FileNme, Password));
                    return (X509Certificate2)htCertificados[FileNme];
                }
                else
                {
                    if (htCertificados[SerialNumber] == null)
                        htCertificados.Add(SerialNumber, GetCertificadoCSP(SerialNumber));
                    return (X509Certificate2)htCertificados[SerialNumber];
                }
            }

        }

        #endregion

        #region GetCertificado

        #region CSP

        /// <summary>
        /// Busca o certificado na CSP
        /// </summary>
        /// <param name="IdCliente"></param>
        /// <returns></returns>
        private static X509Certificate2 GetCertificadoCSP(string SerialNumber)
        {
            X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
            X509Certificate2Collection collection = default(X509Certificate2Collection);
            X509Certificate2Collection collection1 = default(X509Certificate2Collection);
            try
            {
                store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                collection = store.Certificates;

                collection1 = collection.Find(X509FindType.FindBySerialNumber, SerialNumber, false);
                if (collection1.Count > 0)
                {
                    if ((collection1[0].PrivateKey != null))
                    {
                        System.Security.Cryptography.Pkcs.CmsSigner signer = new System.Security.Cryptography.Pkcs.CmsSigner(collection1[0]);
                        return collection1[0];
                    }
                    else
                    {
                        //teste
                        throw new Exception("Certificado invalido.");
                    }

                }
                else
                {
                    throw new Exception("Não foi encontrado um certificado valido.");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                collection = null;
                collection1 = null;
                store.Close();
                store = null;
            }
        }

        #endregion

        #region Arquivo

        private static X509Certificate2 GetCertificadoArquivo(string FileNme, string Password)
        {
            X509Certificate2 certificado = new X509Certificate2(FileNme, Password);
            return certificado;
        }

        #endregion

        #endregion
    }
}
